package com.huarun.common.util;

import java.io.IOException;
import java.security.Key;
import java.util.Date;

import javax.crypto.spec.SecretKeySpec;
import javax.xml.bind.DatatypeConverter;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.alibaba.fastjson.JSONObject;
import com.huarun.redis.RedisKeyPrefix;
import com.huarun.redis.RedisService;
import com.huarun.redis.RedisServiceImpl;

import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.swagger.annotations.ApiOperation;

/**
 * 创建token工具类
 * 
 * <p>
 * Title: JwtUtils
 * </p>
 * 
 * <p>
 * Description:
 * </p>
 * 
 * @author eva
 * 
 * @date 2018年4月24日
 */
public class JwtUtils {

	static String token = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpYXQiOjE1MjQ3MjQzOTUsInN1YiI6IntcImRhdGVcIjoxNTI0NzI0Mzk1OTExLFwiaXBBZGRyZXNzXCI6XCIxOTIuMTY4LjEuNjVcIixcInVzZXJuYW1lXCI6XCJldmFcIn0iLCJpc3MiOiIiLCJhdWQiOiJJQk1TIiwiZXhwIjozMDQ5NDQ4NzkxLCJuYmYiOjE1MjQ3MjQzOTV9.tz1uwbIUA3Wchygt8-HcjdO2_8v9nWpqZJyKXFBEgPk";

	private static RedisService redisService = (RedisService) SpringContextUtils.getBeanByClass(RedisServiceImpl.class);
	private static Logger log = LoggerFactory.getLogger(JwtUtils.class);

	private static int getExpireTime() {
		return PropertyUtil.getProperty("token.expireTime") == null ? Constant.SKEY_EXPIRETIME
				: Integer.valueOf(PropertyUtil.getProperty("token.expireTime"));
	}

	public static void main(String[] args) {

	}
	
	
	/**
	 * 创建token
	 * 
	 * @param map
	 *            个人信息
	 * @param audience
	 *            个人签名
	 * @param issuer
	 *            发送给谁
	 * @param TTLMillis
	 *            时间戳
	 * @param base64Security
	 *            密钥
	 * @return
	 */
	public static String createJWT(JSONObject map, String audience, String issuer, long TTLMillis,
			String base64Security) {
		SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;

		long nowMillis = System.currentTimeMillis();
		Date now = new Date(nowMillis);
		// 生成签名密钥 就是一个base64加密后的字符串？
		byte[] apiKeySecretBytes = DatatypeConverter.parseBase64Binary(base64Security);
		Key signingKey = new SecretKeySpec(apiKeySecretBytes, signatureAlgorithm.getJcaName());
		// 添加构成JWT的参数
		// 创建时间
		// 主题，也差不多是个人的一些信息，为了好的移植，采用了map放个人信息，而没有采用JSON
		// 发送谁
		// 个人签名
		JwtBuilder builder = Jwts.builder().setHeaderParam("typ", "JWT").setIssuedAt(now).setSubject(map.toString())
				.setIssuer(issuer).setAudience(audience).signWith(signatureAlgorithm, signingKey); // 估计是第三段密钥
		// 添加Token过期时间
		if (TTLMillis >= 0) {
			// 过期时间
			long expMillis = nowMillis + TTLMillis;
			// 现在是什么时间
			Date exp = new Date(expMillis);
			// 系统时间之前的token都是不可以被承认的
			builder.setExpiration(exp).setNotBefore(now);
		}
		// 生成JWT
		return builder.compact();
	}

	/**
	 * 校验token
	 * <p>
	 * Title: volidateToken
	 * </p>
	 * <p>
	 * Description: 通过token
	 * 和ip地址校验token是否成功，如果成功，修改redis中的失效时间为10分钟，如果失败，返回false数据库不做修改
	 * </p>
	 * 
	 * @param token
	 *            web端传回的token
	 * @param ipAddress
	 *            request中获取的ip地址
	 * @return 是否校验成功
	 * @throws Exception
	 */
	public static boolean volidateToken(String openId) throws Exception {
		// TODO Auto-generated method stub
		String dbToken = getTokenFromRedis(openId);
		if (null != dbToken) {
			return true;
		}
		return false;
	}

	@ApiOperation(value = "根据token的key值去Redis查找")
	public static String getTokenFromRedis(String tokenKey) {
		return redisService.getValueAddCacheTime(RedisKeyPrefix.USER_TOKEN, tokenKey, getExpireTime());
	}

	@ApiOperation(value = "根据用户名保存token")
	public static String setLoginToken(String tokenName, String token) throws IOException {
		boolean isSuccess = redisService.saveObject(RedisKeyPrefix.USER_TOKEN, tokenName, token, getExpireTime());
		return isSuccess ? token : null;
	}

	@ApiOperation(value = "根据token的key删除token")
	public static String delToken(String tokenName) {
		long delState = redisService.deleteValue(RedisKeyPrefix.USER_TOKEN, tokenName);
		return delState > 0 ? token : null;
	}

	@ApiOperation(value = "根据用户名缓存用户信息")
	public static String setLoginInfo(String userName, String info) throws IOException {
		boolean isSuccess = redisService.saveObject(RedisKeyPrefix.USER_INFO, userName, info, getExpireTime());
		return isSuccess ? token : null;
	}

	@ApiOperation(value = "根据user的key值去Redis查找")
	public static String getLoginInfoFromRedis(String userName) {
		return redisService.getValueAddCacheTime(RedisKeyPrefix.USER_INFO, userName, getExpireTime());
	}

	@ApiOperation(value = "根据用户的key删除用户信息")
	public static String delLoginInfo(String userName) {
		long delState = redisService.deleteValue(RedisKeyPrefix.USER_INFO, userName);
		return delState > 0 ? token : null;
	}

	

//	/**
//	 * 创建token
//	 * 
//	 * @param map
//	 *            个人信息
//	 * @param audience
//	 *            个人签名
//	 * @param issuer
//	 *            发送给谁
//	 * @param TTLMillis
//	 *            时间戳
//	 * @param base64Security
//	 *            密钥
//	 * @return
//	 */
//	public static String createJWT(JSONObject map, String audience, String issuer, long TTLMillis,
//			String base64Security) {
//		SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
//
//		long nowMillis = System.currentTimeMillis();
//		Date now = new Date(nowMillis);
//		// 生成签名密钥 就是一个base64加密后的字符串？
//		byte[] apiKeySecretBytes = DatatypeConverter.parseBase64Binary(base64Security);
//		Key signingKey = new SecretKeySpec(apiKeySecretBytes, signatureAlgorithm.getJcaName());
//		// 添加构成JWT的参数
//		// 创建时间
//		// 主题，也差不多是个人的一些信息，为了好的移植，采用了map放个人信息，而没有采用JSON
//		// 发送谁
//		// 个人签名
//		JwtBuilder builder = Jwts.builder().setHeaderParam("typ", "JWT").setIssuedAt(now).setSubject(map.toString())
//				.setIssuer(issuer).setAudience(audience).signWith(signatureAlgorithm, signingKey); // 估计是第三段密钥
//		// 添加Token过期时间
//		if (TTLMillis >= 0) {
//			// 过期时间
//			long expMillis = nowMillis + TTLMillis;
//			// 现在是什么时间
//			Date exp = new Date(expMillis);
//			// 系统时间之前的token都是不可以被承认的
//			builder.setExpiration(exp).setNotBefore(now);
//		}
//		// 生成JWT
//		return builder.compact();
//	}
}
